﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using ServiceKit.Extensions;
using ServiceKit.JsonRpc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace ServiceKit.WebApi
{
    //[ServiceFilter(typeof(ActionAuditFilterAttribute))]
    public class JsonRpcApiGateWayController : Controller
    {
        private IOptions<RpcServerConfiguration> serverConfig { get; }
        private IRpcInvoker invoker { get; }

        public JsonRpcApiGateWayController(IOptions<RpcServerConfiguration> serverConfig,
            IRpcInvoker invoker)
        {
            this.serverConfig = serverConfig ?? throw new ArgumentNullException(nameof(serverConfig));
            this.invoker = invoker ?? throw new ArgumentNullException(nameof(invoker));
        }

        [HttpGet]
        public string get()
        {
            return "ok";
        }

        [HttpPost]
        [ActionAuditFilter]
        public RpcResponse post()
        {
            var auditData = AuditFilterData.GetOrNull(this);
            string jsonstring = getJsonString(this.HttpContext.Request);
            RpcRequest request = JsonConvert.DeserializeObject<RpcRequest>(jsonstring);
            if (auditData == null)
            {

                var ex = new RpcException(500, "非法请求！");
                RpcError error = new RpcError(ex, true);
                var rpcResponse = new RpcResponse(request.Id, error);
                return rpcResponse;

            }
            else
            {
                auditData.AuditInfo.ServiceName = request.Method;
                auditData.AuditInfo.Parameters = request.Parameters.ToString();
                IEnumerable<object> services = this.HttpContext.RequestServices.GetServices(typeof(IService));
                var response = invoker.InvokeGateWayRequestAsync(request, services);
                return response.Result;
            }
        }

        private string getJsonString(HttpRequest req)
        {
            var bodyStr = "";
            // Allows using several time the stream in ASP.Net Core
            req.EnableRewind();

            // Arguments: Stream, Encoding, detect encoding, buffer size 
            // AND, the most important: keep stream opened

            StreamReader reader = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true);

            bodyStr = reader.ReadToEnd();
            reader.Close();
            reader.Dispose();
            // Rewind, so the core is not lost when it looks the body for the request
            req.Body.Position = 0;
            return bodyStr;
        }
    }
}
